Análisis de datos en R para Ciencia de Datos
Dejad vuestras hojas de cálculo, Anacondas y SAS a un lado
Correo: javalv09@ucm.es. Despacho: 722 (3ª planta). Tutorías: …
Javier Álvarez Liébana, de Carabanchel (Bajo).
Licenciado en Matemáticas (UCM). Doctorado en estadística (UGR).
Encargado de la visualización y análisis de datos covid del Principado de Asturias (2021-2022).
Miembro de la Sociedad Española de Estadística e IO y la Real Sociedad Matemática Española.
Quitarnos el miedo a los errores en programación → a programar se aprende programando
Entender los conceptos básicos de R desde cero → aprender a abstraer ideas y algoritmos
Utilidad de programar → flujos de trabajo reproducibles, transparentes y mantenibles
Introducción al análisis y preprocesamiento de datos → {tidyverse}
Adquirir habilidades en la visualización de datos → {ggplot2}
Entrega I (10%): semana 3-4
Entrega II (30%): semana 8-9
Entrega III (35%): última semana de clase.
Se podrán modificar las fechas por saturación con otras asignaturas siempre y cuando el/la delegado/a lo solicite con más de 10 días de antelación.
Quarto disponibles y actualizadas en https://javieralvarezliebana.es/docencia/R-datascienceEn el menú de las diapositivas (abajo a la izquierda) tienes una opción para descargarlas en pdf en Tools
Material: cuadernos de trabajo y materiales extras y resúmenes de paquetes
🗃 Datos: datasets que usaremos a lo largo de la asignatura, disponibles en https://javieralvarezliebana.es/docencia/R-datascience/material
Instalando R y RStudio. Primeros pasos. Scripts y proyectos
Para el curso los únicos requisitos serán:
Programaremos como escribimos (castellano, por ejemplo) → R es lenguaje
R)RStudio), para escribirloEl lenguaje R será nuestra gramática y ortografía (nuestras reglas de juego)
Paso 1: entra en https://cran.r-project.org/ y selecciona tu sistema operativo.
Paso 2: para Mac basta con que hacer click en el archivo .pkg, y abrirlo una vez descargado. Para sistemas Windows, debemos clickar en install R for the first time y después en Download R for Windows. Una vez descargado, abrirlo como cualquier archivo de instalación.
Paso 3: abrir el ejecutable de instalación.
Cuidado
Siempre que tengas que descargar algo de CRAN (ya sea el propio R o un paquete), asegúrate de tener conexión a internet.
Para comprobar que se ha instalado correctamente, tras abrir R, deberías ver el R GUI(Graphical User Interface), y en él, una pantalla blanca similar a esta: se llama consola y podemos hacer un primer uso de ella como una calculadora.
Para comprobar que se ha instalado correctamente, tras abrir R, deberías ver una pantalla blanca similar a esta: se llama consola y podemos hacer un primer uso de ella como una calculadora.
Primer código: definiremos otra variable llamada b y le asignaremos el valor 2
Fíjate que…
En R asignaremos valores con <- como una flecha: la variable a la izquierda de dicha flecha le asignamos el valor que hay a la derecha (por ejemplo, a <- 1)
Para comprobar que se ha instalado correctamente, tras abrir R, deberías ver una pantalla blanca similar a esta: se llama consola y podemos hacer un primer uso de ella como una calculadora.
Primer código: haremos la suma a + b y nos devolverá su resultado
Fíjate que…
En la consola aparece un número [1]: simplemente es un contador de elementos (como contar filas en un Word)
RStudio será el Word que usaremos para escribir (lo que se conoce como un IDE: entorno integrado de desarrollo).
Paso 1: entra la web oficial de RStudio (ahora llamado Posit) y selecciona la descarga gratuita.
Paso 2: selecciona el ejecutable que te aparezca acorde a tu sistema operativo.
Paso 3: tras descargar el ejecutable, hay que abrirlo como otro cualquier otro y dejar que termine la instalación.
Al abrir RStudio seguramente tengas tres ventanas:
Al abrir RStudio seguramente tengas tres ventanas:
Al abrir RStudio seguramente tengas tres ventanas:
R es la evolución del trabajo de los laboratorios Bell con el lenguaje S, que fue llevado al mundo del software libre por Ross Ihaka y Robert Gentleman en los años 90. La version R 1.0.0 se publicó el 29 de febrero de 2000.
R es el lenguaje estadístico por excelencia, creado por y para estadísticos/as, con 6 ventajas fundamentales frente a Excel, SAS, Stata o SPSS:
R es el compartir código bajo copyleft → uso ético de dinero y algoritmosR es el lenguaje estadístico por excelencia, creado por y para estadísticos/as, con 6 ventajas fundamentales frente a Excel, SAS, Stata o SPSS:
Automatizar → te permitirá automatizar tareas recurrentes.
Replicabilidad → podrás replicar tu análisis siempre de la misma manera.
Flexibilidad → podrás adaptar el software a tus necesidades.
Transparencia → ser auditado por la comunidad.
Una de las ideas claves de R es el uso de paquetes: códigos que otras personas han implementado para resolver un problema
Una vez instalado, hay dos manera de usar un paquete (traerlo de la estantería)
library(), usando el nombre del paquete sin comillas, cargamos en la sesión todo el libroDurante tu aprendizaje va a ser muy habitual que las cosas no salgan a la primera → te vas equivocar. No solo será importante asumirlo sino que es importante leer los mensajes de error para aprender de ellos.
Un script será el documento en el que programamos, nuestro archivo .doc (aquí con extensión .R) donde escribiremos las órdenes. Para abrir nuestro primero script, haz click en el menú en File < New File < R Script.
Cuidado
Es importante no abusar de la consola: todo lo que no escribas en un script, cuando cierres, lo habrás perdido.
Cuidado
R es case-sensitive: es sensible a mayúsculas y minúsculas por lo que x y X representa variables distintas.
Ahora tenemos una cuarta ventana: la ventana donde escribiremos nuestros códigos. ¿Cómo ejecutarlo?
Save current document.Ctrl+EnterDe la misma manera que en el ordenador solemos trabajar de manera ordenada por carpetas, en RStudio podemos hacer lo mismo para trabajar de manera eficaz creando proyectos.
Un proyecto será una «carpeta» dentro de RStudio, de manera que nuestro directorio raíz automáticamente será la propia carpeta de proyecto (pudiendo pasar de un proyecto a otro con el menu superior derecho).
Podemos crear uno en una carpeta nueva o en una carpeta ya existente.
📝 Crea en tu ordenador una carpeta de la asignatura y crea dentro de ella el proyecto de RStudio: es ahí donde vas a guardar todo lo que hagamos a lo largo de este curso.Tras crear el proyecto tendrás un archivo R Project. A continuación crea en dicha carpeta dos subcarpetas: datos (es ahí donde irás guardando los distintos datasets que usaremos) y scripts (es ahí donde irás guardando los archivos .R de cada clase)
📝 Dentro del proyecto crea un script ejercicios-clase1.R (dentro de la carpeta scripts). Una vez creado define en él una variable de nombre a y cuyo valor sea -1. Ejecuta el código de las 3 maneras explicadas.
📝 Añade debajo otra línea para definir una variable b con el valor 5. Tras ello guarda la multiplicación de ambas variables. Ejecuta el código como consideres.
📝 Modifica el código inferior para definir dos variables c y d, con valores 3 y -1. Tras ello divide las variables y guarda el resultado.
📝 Asigna un valor positivo a x y calcula su raíz cuadrada; asigna otro negativo y y calcula su valor absoluto con la función abs().
Toma nota
Comandos como sqrt(), abs() o max() son lo que llamamos funciones: líneas de código que hemos «encapsulado» bajo un nombre, y dado unos argumentos de entrada, ejecuta las órdenes (una especie de atajo). En las funciones los argumentos irán SIEMPRE entre paréntesis
📝 Usando la variable x ya definida, completa/modifica el código inferior para guardar en una nueva variable z el resultado guardado en x menos 5.
📝 Define una variable x y asígnale el valor -1. Define otra y y asígnale el valor 0. Tras ello realiza las operaciones a) x entre y; b) raíz cuadrada de x. ¿Qué obtienes?
¿Qué tipos de celdas (datos) existen? Concatenando celdas: vectores
¿Qué tipo de dato podemos tener en cada celda de una tabla?
Antes de seguir, es importante que sepas algo cuánto antes: empezar en la programación puede ser frustrante
Al igual que cuando aprendes un idioma nuevo, el primer obstáculo a solventar no es tanto qué decir sino cómo decirlo de manera correcta. Y en R pasa lo mismo, así que vamos a normalizar nuestra forma de programar lo máximo posible para evitar errores futuros.
R no procesa los espacios)snake_caseTools < Global Options puedes personalizar algunas opciones de RStudio. En Code < Display podemos indicarle en Show margin que los scripts nos muestren un margen “imaginario” (no interacciona con el código) para “forzarnos” a realizar un salto de línea.RStudio tenemos una herramienta maravillosa: si escribes parte del nombre de una variable o función y tabulas, RStudio te autocompletaTools < Global Options < Code < Display y activa la opción Rainbow parenthesesRStudio te avisará.¿Existen variables más allá de los números en la ciencia de datos? Piensa por ejemplo en los datos que podrías guardar de una persona:
TRUE si está matriculado o FALSE en otro caso).El dato más sencillo (ya lo hemos usado) serán las variables numéricas
Para saber su tipología (naturaleza o formato) variable tenemos typeof()
[1] "double"
[1] "integer"
Fíjate que…
En R tenemos una colección de funciones que empiezan por as.x() y que sirven como funciones de conversión: un dato que era de un tipo, lo convertimos a tipo x.
Además de los números «normales» tendremos el valor más/menos infinito codificado como Inf o -Inf
Con las variables numéricas podemos realizar las operaciones aritméticas de una calculadora: sumar (+)…
Imagina que además de la edad de una persona queremos guardar su nombre: ahora la variable será de tipo character
Las cadenas de texto son un tipo con el que obviamente no podremos hacer operaciones aritméticas (sí otras operaciones como pegar o localizar patrones).
Recuerda que…
Las variables de tipo texto (character o string) van SIEMPRE entre comillas: no es lo mismo TRUE (valor lógico, binario) que "TRUE" (texto).
Como hemos comentado R llamaremos función a un trozo de código encapsulado bajo un nombre, y que depende de unos argumentos de entrada. Nuestra primera función será paste(): dadas dos cadenas de texto nos permite pegarlas.
¿Cómo saber qué argumentos necesita una función? Escribiendo en consola ? paste te aparecerá una ayuda en el panel multiusos.
En dicha ayuda podrás ver en su cabecera que argumentos ya tiene asignados por defecto la función
Los argumentos (y su detalle) también pueden ser consultado tabulando (detras una coma).
Es muy importante entender el concepto de argumento por defecto de una función en R: es un valor que la función usa pero a veces podemos no ver porque ya tiene un valor asignado.
[1] "Javier Álvarez"
[1] "Javier Álvarez"
Toma nota
El operador = lo reservaremos para asignar argumentos dentro de funciones. Para todas las demás asignaciones usaremos <-
Una forma más intuitiva de trabajar con textos es usar el paquete {glue}: lo primero que haremos será «comprar el libro» (si nunca lo hemos hecho). Tras ello cargamos el paquete
Con la función glue() de dicho paquete podemos usar variables dentro de cadenas de texto. Por ejemplo, «la edad es de … años», donde la edad está guardada en una variable.
Otro tipo fundamental serán las variables lógicas o binarias (dos valores):
TRUE: verdadero guardado internamente como un 1.FALSE: falso guardado internamente como un 0.Como veremos en breve, las variables lógicas en realidad puede tomar un tercer valor: NA o dato ausente, representando las siglas de not available, y será muy habitual encontrarlo dentro de una base de datos.
Los valores lógicos suelen ser resultado de evaluar condiciones lógicas. Por ejemplo, imaginemos que queremos comprobar si una persona se llama Javi.
Con el operador lógico == preguntamos sí lo que tenemos guardado a la izquierda es igual que lo que tenemos a la derecha: es una pregunta
Fíjate que…
No es lo mismo <- (asignación) que == (estamos preguntando, es una comparación lógica).
Además de las comparaciones «igual a» frente «distinto», también comparaciones de orden como menor que <, mayor que >, <= o >=.
¿Tiene la persona menos de 32 años?
Un tipo de datos muy especial: los datos de tipo fecha.
Parece una simple cadena de texto pero debería representar un instante en el tiempo. ¿Qué debería suceder si sumamos un 1 a una fecha?
Las fechas NO pueden ser texto: debemos convertir la cadena de texto a fecha.
Una vez instalado, de todos los paquetes (libros) que tenemos, le indicaremos que nos cargue ese concretamente.
Para convertir a tipo fecha usaremos la función as_date() del paquete {lubridate} (por defecto en formato yyyy-mm-dd)
En as_date() el formato de fecha por defecto es yyyy-mm-dd así si la cadena de texto no se introduce de manera adecuada…
Para cualquier otro formato debemos especificarlo en el argumento opcional format = ... tal que %d representa días, %m meses, %Y en formato de 4 años y %y en formato de 2 años.
En dicho paquete tenemos funciones muy útiles para manejar fechas:
today() podemos obtener directamente la fecha actual.Amplia contenido
Tienes un resumen en pdf de los paquetes más importantes en la carpeta correspondiente en el campus
Intenta realizar los siguientes ejercicios sin mirar las soluciones
📝 Define una variable que guarde tu edad (llamada edad) y otra con tu nombre (llamada nombre)
📝 Comprueba con dicha variable edad si NO tiene 60 años o si se llama "Ornitorrinco" (debes obtener variables lógicas como resultado)
📝 ¿Por qué el código inferior da error?
📝 Define otra variable llamada hermanos que responda la pregunta «¿tienes hermanos?» y otra variable que almacene tu fecha de nacimiento (llamada fecha_nacimiento).
📝 Define otra variable con tus apellidos (llamada apellidos) y usa glue() para tener, en una sola variable llamada nombre_completo, tu nombre y apellidos separando nombre y apellido por una coma
Cuando trabajamos con datos normalmente tendremos columnas que representan variables: llamaremos vectores a una concatenación de celdas (valores) del mismo tipo (lo que sería una columna de una tabla).
La forma más sencilla es con el comando c() (c de concatenar), y basta con introducir sus elementos entre paréntesis y separados por comas
Consejo
Un número individual x <- 1 (o bien x <- c(1)) es en realidad un vector de longitud uno –> todo lo que sepamos hacer con un número podemos hacerlo con un vector de ellos.
El vector más famoso será el de tipo numérico, y en concreto, las conocidas como secuencias numéricas (por ejemplo, los días del mes), usadas para, entre otras cosas, indexar bucles.
El comando seq(inicio, fin) nos permite crear una secuencia numérica desde un elemento inicial hasta uno final, avanzando de uno en uno.
Un atajo es el comando 1:n, que nos devuelve lo mismo que seq(1, n)
Si el elemento inicial es mayor que el final, entenderá que la secuencia es en orden decreciente.
Otras veces nos interesará definir una secuencia con una longitud concreta
[1] 1.000000 9.166667 17.333333 25.500000 33.666667 41.833333 50.000000
Incluso puede nos interese generar un vector de n elementos repetidos
Un vector es una concatenación de elementos del mismo tipo, pero no tienen porque ser necesariamente números. Vamos a crear una frase de ejemplo.
¿Qué sucederá si concatenamos elementos de diferente tipo?
Fíjate que como todos tienen que ser del mismo tipo, lo que hace R es convertir todo a texto, violando la integridad del dato
Con los vectores numéricos podemos hacer las mismas operaciones aritméticas que con los números → un número es un vector (de longitud uno)
¿Qué sucederá si sumamos o restamos un valor a un vector?
Los vectores también pueden interactuar entre ellos, así que podemos definir, por ejemplo, sumas de vectores (elemento a elemento)
Dado que la operación (por ejemplo, una suma) se realiza elemento a elemento, ¿qué sucederá si sumamos dos vectores de distinta longitud?
Una operación muy habitual es preguntar a los datos mediante el uso de condiciones lógicas. Por ejemplo, si definimos un vector de temperaturas…
¿Qué días hizo menos de 22 grados?
Nos devolverá un vector lógico, en función de si cada elemento cumple o no la condición pedida (de igual longitud que el vector preguntado)
Las condiciones lógicas pueden ser combinadas de dos maneras:
&) para devolver un TRUE|)Otra operación muy habitual es la de acceder a elementos. La forma más sencilla es usar el operador [i] (acceder al elemento i-ésimo)
Dado que un número no es más que un vector de longitud uno, esta operación también la podemos aplicar usando un vector de índices a seleccionar
Consejo
Para acceder al último, sin preocuparnos de cuál es, podemos pasarle como índice la propia longitud x[length(x)]
Otras veces no querremos seleccionar sino eliminar algunos elementos. Deberemos repetir la misma operación pero con el signo - delante: el operador [-i] no selecciona el elemento i-ésimo del vector sino que lo «des-selecciona»
En muchas ocasiones los queremos seleccionar o eliminar en base a condiciones lógicas, en función de los valores, así que pasaremos como índice la propia condición (recuerda, x < 2 nos devuelve un vector lógico)
También podemos hacer uso de operaciones estadísticas como por ejemplo sum() que, dado un vector, nos devuelve la suma de todos sus elementos.
¿Qué sucede cuando falta un dato (ausente)?
Como hemos comentado que los valores lógicos son guardados internamente como 0 y 1, podremos usarlos en operaciones aritméticas.
Por ejemplo, si queremos averiguar el número de elementos que cumplen una condición (por ejemplo, menores que 3), los que lo hagan tendrán asignado un 1 (TRUE) y los que no un 0 (FALSE) , por lo que basta con sumar dicho vector lógico para obtener el número de elementos que cumplen
Otra operación habitual que puede sernos útil es la suma acumulada con cumsum() que, dado un vector, nos devuelve un vector a su vez con el primero, el primero más el segundo, el primero más el segundo más el tercero…y así sucesivamente.
¿Qué sucede cuando falta un dato (ausente)?
En el caso de la suma acumulada lo que sucede es que a partir de ese valor, todo lo acumulado posterior será ausente.
Otra operación habitual que puede sernos útil es la diferencia (con retardo) con diff() que, dado un vector, nos devuelve un vector con el segundo menos el primero, el tercero menos el segundo, el cuarto menos el tercero…y así sucesivamente.
Otras operaciones habituales son la media, mediana, percentiles, etc.
Otras operaciones habituales son la media, mediana, percentiles, etc.
Por último, una acción habitual es saber ordenar valores:
sort(): devuelve el vector ordenado. Por defecto de menor a mayor pero con decreasing = TRUE podemos cambiarlo[1] 7 20 23 25 33 41 65 77 81
[1] 81 77 65 41 33 25 23 20 7
Intenta realizar los siguientes ejercicios sin mirar las soluciones
📝 Define el vector x como la concatenación de los 5 primeros números impares. Calcula la longitud del vector
📝 Accede al tercer elemento de x. Accede al último elemento (sin importar la longitud, un código que pueda ejecutarse siempre). Elimina el primer elemento.
📝 Obtén los elementos de x mayores que 4. Calcula el vector 1/x y guárdalo en una variable.
📝 Crea un vector que represente los nombres de 5 personas, de los cuales uno es desconocido.
📝 Encuentra del vector x de ejercicios anteriores los elementos mayores (estrictos) que 1 Y ADEMÁS menores (estrictos) que 7. Encuentra una forma de averiguar si todos los elementos son o no positivos.
📝 Dado el vector x <- c(1, -5, 8, NA, 10, -3, 9), ¿por qué su media no devuelve un número sino lo que se muestra en el código inferior?
📝 Dado el vector x <- c(1, -5, 8, NA, 10, -3, 9), extrae los elementos que ocupan los lugares 1, 2, 5, 6.
📝 Dado el vector x del ejercicio anterior, ¿cuales tienen un dato ausente? Pista: las funciones is.algo() comprueban si el elemento es tipo algo (tabula)
📝 Define el vector x como la concatenación de los 4 primeros números pares. Calcula el número de elementos de x menores estrictamente que 5.
📝 Calcula el vector 1/x y obtén la versión ordenada (de menor a mayor) de las dos formas posibles
En el paquete {datasets} (ya instalado por defecto) tenemos diversos conjuntos de datos y uno de ellos es airquality. Debajo te he extraído 3 variables de dicho dataset (fíjate que se hace con datos$variable)
Intenta responder a las preguntas planteadas en el workbook
Haciendo uso de ? ... podemos consultar en el panel de ayuda lo que significa el objeto.
date con la fecha de cada registro (combinando año, mes y día)[1] 31
[1] 31
[1] 0
[1] 83.96774
[1] 28.87097
[1] "1973-06-08" "1973-06-09" "1973-06-10" "1973-06-11" "1973-06-12"
[6] "1973-07-07" "1973-07-08" "1973-07-09" "1973-07-10" "1973-07-14"
[11] "1973-07-19" "1973-07-28" "1973-08-06" "1973-08-07" "1973-08-08"
[16] "1973-08-09" "1973-08-10" "1973-08-27" "1973-08-28" "1973-08-29"
[21] "1973-08-30" "1973-08-31" "1973-09-01" "1973-09-02" "1973-09-03"
[26] "1973-09-04" "1973-09-05"
[1] 27
[1] 27
ordenar
microbenchmark
Profundizando en variables de tipo texto. Primeras bases de datos
Intenta realizar los siguientes ejercicios sin mirar las soluciones
📝 …
📝 …
📝 …
📝 …
📝
Cuando analizamos datos solemos tener varias variables de cada individuo: necesitamos una «tabla» que las recopile. La opción más inmediata son las matrices: concatenación de variables del mismo tipo e igual longitud.
Imagina que tenemos estaturas y pesos de 4 personas. ¿Cómo crear un dataset con las dos variables?
También podemos construir la matriz por filas con la función rbind() (concatenar - bind - por filas - rows), aunque lo recomendable es tener cada variable en columna e individuo en fila como luego veremos.
[,1] [,2] [,3] [,4]
estaturas 150 160 170 180
pesos 63 70 85 95
View(matriz).También podemos «darle vuelta» (matriz transpuesta) con t().
Dado que ahora tenemos dos dimensiones en nuestros datos, para acceder a elementos con [] deberemos proporcionar dos índices separados por comas: índice de la fila y de la columna
En algunas casos querremos obtener los datos totales de un individuo (una fila concreta pero todas las columnas) o los valores de toda una variable para todos los individuos (una columna concreta pero todas las filas). Para ello dejaremos sin rellenar uno de los índices
estaturas pesos
160 70
[1] 150 160 170 180
También podemos definir una matriz a partir de un vector numérico, reorganizando los valores en forma de matriz (sabiendo que los elementos se van colocando por columnas).
Con las matrices sucede como con los vectores: cuando aplicamos una operación aritmética lo hacemos elemento a elemento
También podemos realizar operaciones por columnas/filas sin recurrir a bucles con la función apply(), y le indicaremos como argumentos
MARGIN = 1 por filas, MARGIN = 2 por columnas)Intenta realizar los siguientes ejercicios sin mirar las soluciones
📝 Modifica el código inferior para definir una matriz x de unos, de 3 filas y 7 columnas.
📝 A la matriz anterior, suma un 1 a cada número de la matriz y divide el resultado entre 5. Tras ello calcula su transpuesta
📝 ¿Por qué el código inferior nos devuelve dicho mensaje de aviso?
📝 Define la matriz x <- matrix(1:12, nrow = 4). Tras ello obtén los datos del primer individuo, los datos de la tercera variable, y el elemento (4, 1).
📝 Define una matriz de 2 variables y 3 individuos tal que cada variable capture la estatura y la edad 3 personas, de manera que la edad de la segunda persona sea desconocida (ausente). Tras ello calcula la media de cada variable (¡nos debe de volver un número!)
Las matrices tienen el mismo problema que los vectores: si juntamos datos de distinto tipo, se perturba la integridad del dato ya que los convierte (fíjate en el código inferior: las edades y los TRUE/FALSE los ha convertido a texto)
Para poder trabajar con variables de distinto tipo tenemos en R lo que se conoce como data.frame: concatenación de variables de igual longitud pero que pueden ser de tipo distinto.
Dado que un data.frame es ya un intento de «base de datos» las variables no son meros vectores matemáticos: tienen un significado y podemos (debemos) ponerles nombres que describan su significado
¡TENEMOS NUESTRO PRIMER CONJUNTO DE DATOS! (estrictamente no podemos hablar de base de datos pero de momento como lo si fuesen). Puedes visualizarlo escribiendo su nombre en consola o con View(tabla)
Si queremos acceder a sus elementos, al ser de nuevo datos tabulados, podemos acceder como en las matrices (no recomendable): de nuevo tenemos dos índices (filas y columnas, dejando libre la que no usemos)
edad estado nombre f_nacimiento
2 24 NA laura 1992-04-01
[1] "javi" "laura" "lucía"
[1] 24
Pero también tiene las ventajas de una «base» de datos : podemos aceder a las variables por su nombre (lo recomendable ya que las variables pueden cambiar de posición y ahora sí tienen un significado), poniendo el nombre de la tabla seguido del símbolo $ (con el tabulador, nos aparecerá un menú de columnas a elegir)
names(): nos muestra los nombres de las variablesSi tenemos uno ya creado y queremos añadir una columna es tan simple como usar la función data.frame() que ya hemos visto para concatenar la columna. Vamos añadir por ejemplo una nueva variable, el número de hermanos de cada individuo.
Las tablas en formato data.frame tienen algunas limitaciones. La principal es que no permite la recursividad: imagina que definimos una base de datos con estaturas y pesos, y queremos una tercera variable con el IMC
Error in data.frame(estatura = c(1.7, 1.8, 1.6), peso = c(80, 75, 70), : objeto 'peso' no encontrado
En adelante usaremos el formato tibble (data.frame mejorado) del paquete {tibble}
datos_tb <-
tibble("estatura" = c(1.7, 1.8, 1.6), "peso" = c(80, 75, 70), "IMC" = peso / (estatura^2))
datos_tb# A tibble: 3 × 3
estatura peso IMC
<dbl> <dbl> <dbl>
1 1.7 80 27.7
2 1.8 75 23.1
3 1.6 70 27.3
Las tablas en formato tibble nos permitirá una gestión más ágil, eficiente y coherente de los datos, con 4 ventajas principales:
tribble()Consejo
El paquete {datapasta} nos permite copiar y pegar tablas de páginas web y documentos sencillos
R por defecto las operaciones se hacen elemento a elementoIntenta realizar los siguientes ejercicios sin mirar las soluciones
📝 Carga del paquete {datasets} el conjunto de datos airquality (variables de la calidad del aire de Nueva York desde mayo hasta septiembre de 1973). ¿Es el conjunto de datos airquality de tipo tibble? En caso negativo, conviértelo a tibble (busca en la documentación del paquete en https://tibble.tidyverse.org/index.html).
📝 Una vez convertido a tibble obtén el nombre de las variables y las dimensiones del conjunto de datos. ¿Cuántas variables hay? ¿Cuántos días se han medido?
📝 Filtra solo los datos del mes de agosto. ¿Cómo indicarle que queremos solo las filas que cumplan una condición concreta? (pista: en realidad todo son vectores “formateados”)
📝 Selecciona aquellos datos que no sean ni de julio ni de agosto.
📝 Modifica el siguiente código para quedarte solo con las variable de ozono y temperatura (sin importar qué posición ocupen)
📝 Selecciona los datos de temperatura y viento de agosto.
Del paquete Biostatistics usaremos el conunto de datos pinniped
tibble (renombra con pinniped_tb)[1] "data.frame"
Phoca o no.[1] TRUE
[1] FALSE
# A tibble: 33 × 8
Species Male_brain_g Female_brain_g Male_mass_Kg Female_mass_Kg Mate_type
<chr> <dbl> <dbl> <dbl> <dbl> <chr>
1 Monachus s… 370 NA 173 272. mono
2 Monachus m… 480 480 260 275 mono
3 Mirounga a… 700 640 2275 488 poly
4 Mirounga l… 1431. 899. 3510 566. poly
5 Leptonycho… 535 638. 450 447 poly
6 Ommatophoc… 425 530 154. 164 mono
7 Lobodon ca… 578. 539. 220. 224 mono
8 Hydrurga l… 765 660 324 367 mono
9 Cystophora… 480 430 343. 222. mono
10 Erignathus… NA 460 312. 326 mono
# ℹ 23 more rows
# ℹ 2 more variables: phoca <lgl>, dif_m_f <dbl>
Estructuras condicionales y bucles
Una estructura de control se compone de una serie de comandos orientados a decidir el camino que tu código debe recorrer
Si se cumple la condición A, ¿qué sucede?
¿Y si sucede B?
¿Cómo puedo repetir una misma expresión (dependiendo de una variable)?
Si has programado antes, quizás te sea familiar las conocidas como estructuras condicionales tales como if (blabla) {...} else {...} o bucles for/while (a evitar siempre que podamos).
Una de las estructuras de control más famosas son las conocidas como estructuras condicionales if.
SI (IF) un conjunto de condiciones se cumple (TRUE), entonces ejecuta lo que haya dentro de las llaves
Por ejemplo, la estructura if (x == 1) { código A } lo que hará será ejecutar el código A entre llaves pero SOLO SI la condición entre paréntesis es cierta (solo si x es 1). En cualquier otro caso, no hará nada.
Nuestra estructura condicional hará lo siguiente: si existe algún menor de edad, imprimirá por pantalla un mensaje.
En caso de que las condiciones no sean ciertas dentro de if() (FALSE), no sucede nada
No obtenemos ningún mensaje porque la condición all(edad >= 18) no es TRUE, así que bno ejecuta nada.
La estructura if (condicion) { código A } puede combinarse con un else { código B }: cuando la condición no está verificada, se ejecutará el código alternativo B dentro de else { }, permitiéndonos decidir que sucede cuando se cumple y cuando no. . . .
Por ejemplo, if (x == 1) { código A } else { código B } ejecutará A si x es igual a 1 y B en cualquier otro caso.
Esta estructura if - else puede ser anidada: imagina que queremos ejecutar un código si todos son menores; si no sucede, pero todos son mayores de 16, hacer otra cosa; en cualquier otra cosa, otra acción.
if (all(edad >= 18)) {
print("Todos son mayores de edad")
} else if (all(edad >= 16)) {
print("Hay algún menor de edad pero todos con 16 años o más")
} else { print("Hay alguna persona con menos de 16 años") }[1] "Hay alguna persona con menos de 16 años"
Truco
Puedes colapsar las estructuras haciendo click en la flecha a la izquierda que aparece en tu script.
Esta estructura condicional se puede vectorizar (en una sola línea) con if_else() (del paquete {dplyr}), cuyos argumentos son
NAPor ejemplo, vamos a etiquetar sin son mayores/menores de edad y un “desconocido” cuando no conocemos la edad
Aunque en la mayoría de ocasiones se pueden reemplazar por otras estructuras más eficientes y legibles, es importante conocer una de las expresiones de control más famosas: los bucles.
for { }: permite repetir el mismo código en un número prefijado y conocido de veces.
while { }: permite repetir el mismo código pero en un número indeterminado de veces (hasta que una condición deje de cumplirse).
Un bucle for es una estructura que permite repetir un conjunto de órdenes un número finito, prefijado y conocido de veces dado un conjunto de índices.
Por ejemplo, vamos a definir un vector x y vamos a imprimir sus elementos al cuadrado: definireos un índice i para imprimir, en cada paso, el valor i-ésimo x[i]^2. Esos índices irán dentro de for (indice in conjunto) { code } (por ejemplo, i in 1:4)
Dentro del paréntesis del for () debemos tener una secuencia de índices (en este caso, números). Si queremos hacer lo mismo pero excluyendo el segundo elemento simplemente definimos el conjunto de valores c(1, 3, 4) entre los que i puede moverse.
Otra forma de usar un bucle es definir de cero un vector: primer inicializamos en ceros y <- rep(0, 4) para después modificar cada elemento i-ésimo definidos como x[i]^2.
Como ya hemos aprendido con el paquete{microbenchmark} podemos chequear como los bucles suelen ser muy ineficientes (de ahí que debamos evitarlos en la mayoría de ocasiones
library(microbenchmark)
x <- 1:1000
microbenchmark(y <- x^2,
for (i in 1:100) { y[i] <- x[i]^2 },
times = 500)Unit: nanoseconds
expr min lq mean median
y <- x^2 800 902 1548.198 1401
for (i in 1:100) { y[i] <- x[i]^2 } 984000 1025551 1112320.182 1048801
uq max neval cld
1601 30800 500 a
1083501 2941601 500 b
Podemos ver otro ejemplo combinando números y textos: definimos un vector de edades y de nombres, e imprimimos el nomber y edad i-ésima.
Fíjate que si no queremos estar pendientes de cuantos valores tenemos, podemos hacer uso de length() para acceder a la última posición (sea cual sea).
Aunque normalmente se suelen indexar con vectors numéricos, los bucles pueden ser indexados sobre cualquier estructura vectorial
Vamos a combinar las estructuras condicionales y los bucles: usando el conjunto swiss del paquete {datasets}, vamos a asignar NA si los valores de fertilidad son mayores de 80.
Otra forma de crear un bucle es con la estructura while { }, que nos ejecutará un bucle un número desconocido de veces, hasta que una condición deje de cumplirse (de hecho puede que nunca termine). Por ejemplo, vamos a inializar una variable ciclos <- 1, que incrementaremos en cada paso, y no saldremos del bucle hasta que ciclos > 4.
¿Qué sucede cuando la condición nunca es FALSE? Pruébalo tu mismo
Cuidado
Un bucle while { } puede ser bastante «peligroso» sino controlamos bien cómo pararlo.
Contamos con dos palabras reservadas para abortar un bucle o forzar su avance:
break: permite abortar un bucle incluso si no se ha llegado a su finalContamos con dos palabras reservadas para abortar un bucle o forzar su avance:
next: fuerza un bucle a avanzar a la siguiente iteraciónAunque no es tan usado como las opciones anteriores, también contamos con repeat { } que ejecuta un bucle de manera infinita hasta que se indique abortar con un break
Por último, otra forma de repetir código un número de veces es hacer uso de replicate(): simplemente permite repetir lo mismo n veces
📝 Modifica el código inferior para que se imprima un mensaje por pantalla si y solo si todos los datos de airquality son con mes distinto a enero
📝 Modifica el código inferior para guardar en una variable llamada temp_alta un TRUE si alguno de los registros tiene una temperatura superior a 90 grados Farenheit y FALSE en cualquier otro caso
📝 Modifica el código inferior para diseñar un bucle for de 5 iteraciones que solo recorra los primeros 5 impares (y en cada paso del bucle los imprima)
Javier Álvarez Liébana • Grado en Ciencia de Datos Aplicada (UCM)